home *** CD-ROM | disk | FTP | other *** search
/ Light ROM 1 / LIGHT-ROM 1 (Amiga Library Services)(1994).iso / ffdisks / d941.lha / YAMFG / Source / YAMFG.FraníÂis < prev    next >
Text File  |  1993-12-20  |  27KB  |  869 lines

  1. ; YAMFG 1.0 - ©1993 F.Delacroix- FreeWare
  2. ; écrit sur le Devpac 3 d'Hisoft
  3.  
  4. ; tous les includes system ont été ajoutés au moment de l'as-
  5. ; semblage grâce à un fichier .gs de Devpac 3. Si vous utili-
  6. ; sez un autre assembleur,ajoutez-les manuellement.
  7.  
  8.     include    exec/execbase.i        ; d'autres includes: struct ExecBase
  9.     include    hardware/custom.i    ; custom hardware: nombres aléatoires
  10.     include    libraries/reqtools.i    ; includes pour reqtools.library
  11.     include    libraries/reqtools_lib.i
  12.  
  13. DEFAULT_WIDTH    EQU    20    ; constantes utiles: évidentes
  14. DEFAULT_HEIGHT    EQU    20
  15. DEFAULT_MINES    EQU    40
  16. MAX_WIDTH    EQU    24
  17. MAX_HEIGHT    EQU    21
  18. UP    EQU    $4c        ; touches utilisées pour bouger le tank
  19. DOWN    EQU    $4d
  20. RIGHT    EQU    $4e
  21. LEFT    EQU    $4f
  22. STATUSX    EQU    4    ; coordonnées pour la ligne status
  23. STATUSY    EQU    18
  24.  
  25.     move.l    4.w,a6
  26.     move.l    ThisTask(a6),a4    ;trouve la tâche (même chose que FindTask(0))
  27.     moveq    #0,d0
  28.     tst.l    pr_CLI(a4)    ; venons-nous du CLI ?
  29.     bne.s    FromCLI    ; oui...
  30.     lea    pr_MsgPort(a4),a0    ; non: allons chercher le message
  31.     jsr    _LVOWaitPort(a6)    ; WBStartup envoyé par le Workbench
  32.     lea    pr_MsgPort(a4),a0
  33.     jsr    _LVOGetMsg(a6)
  34. FromCLI    move.l    d0,WBStarter    ; et rangeons-le (0 pour le CLI)
  35.  
  36.     lea    ReqTools.Name(pc),a1    ; ouvrons la reqtools.library
  37.     moveq    #0,d0
  38.     jsr    _LVOOpenLibrary(a6)
  39.     move.l    d0,ReqTools.Base
  40.     beq    OutOfHere    ; pas de reqtools.library: fin du programme
  41.  
  42.     move.l    ReqTools.Base(pc),a0    ; et prenons-y les bases des autres
  43.     move.l    rt_IntuitionBase(a0),Intuition.Base    ; bibliothèques
  44.     move.l    rt_GfxBase(a0),Graphics.Base
  45.  
  46.     lea    YAMFG.NewWindow(pc),a0    ; ouvrons la fenêtre
  47.     move.l    Intuition.Base(pc),a6
  48.     jsr    _LVOOpenWindow(a6)
  49.     move.l    d0,YAMFG.Window
  50.     beq    CloseReqTools    ; pas de fenêtre !
  51.  
  52.     move.l    YAMFG.Window(pc),a0    ; attachons les menus à la fenêtre
  53.     lea    Project.Menu(pc),a1
  54.     jsr    _LVOSetMenuStrip(a6)
  55.     tst.l    d0
  56.     beq    CloseWindow    ; raté ! (ne devrait pas arriver)
  57.  
  58.     move.l    YAMFG.Window(pc),a0    ; données importantes pour la fenêtre
  59.     move.l    wd_RPort(a0),YAMFG.RastPort    ; RastPort pour les graphismes
  60.     move.l    wd_UserPort(a0),YAMFG.UserPort    ; UserPort pour les messages
  61.     bra    NewGame    ; commençons une nouvelle partie
  62.  
  63. WaitMessage
  64.     move.l    YAMFG.UserPort(pc),a0    ; attends un message envoyé par
  65.     move.l    4.w,a6            ; Intuition à notre fenêtre...
  66.     jsr    _LVOWaitPort(a6)
  67. NextMessage
  68.     move.l    YAMFG.UserPort(pc),a0    ; et vas le chercher!
  69.     move.l    4.w,a6
  70.     jsr    _LVOGetMsg(a6)
  71.     tst.l    d0
  72.     beq.s    WaitMessage    ; Y en a-t-il vraiment un ?
  73.     move.l    d0,a1        ; Oui !
  74.     move.l    im_Class(a1),d7        ; Sauve les champs importants:Classe
  75.     move.w    im_Code(a1),d6        ; et Code
  76.     jsr    _LVOReplyMsg(a6)    ; et réponds à Intuition
  77.     cmp.l    #IDCMP_CLOSEWINDOW,d7    ; Devons-nous quitter ?
  78.     beq    ClearMenus        ; Oui? Alors partons...
  79.     cmp.w    #IDCMP_RAWKEY,d7    ; A-t-on appuyé sur une touche?
  80.     bne    NoRawKey
  81.     btst    #IECODEB_UP_PREFIX,d6    ; ignore si une touche a été lachée
  82.     bne    NextMessage
  83.     tst.b    FinishFlag    ; Le jeu est-il terminé ?
  84.     bne    NewGame        ; oui? alors commence une nouvelle partie
  85.     move.w    MinerX(pc),d0    ; non: prend la position du tank
  86.     move.w    MinerY(pc),d1
  87.  
  88.     cmp.w    #UP,d6        ; Haut ?
  89.     beq.s    GoUp
  90.     cmp.w    #DOWN,d6    ; Bas ?
  91.     beq.s    GoDown
  92.     cmp.w    #RIGHT,d6    ; Droite ?
  93.     beq.s    GoRight
  94.     cmp.w    #LEFT,d6    ; Ou gauche ?
  95.     bne    NextMessage    ; Rien de cela ?? alors prochain message
  96.  
  97.     subq.w    #1,d0        ; 1 case à gauche
  98.     bra.s    DirectionGot
  99. GoRight    addq.w    #1,d0        ; 1 case à droite
  100.     bra.s    DirectionGot
  101. GoDown    addq.w    #1,d1        ; 1 case en bas
  102.     bra.s    DirectionGot
  103. GoUp    subq.w    #1,d1        ; 1 case en haut
  104.  
  105. DirectionGot
  106.     bsr    CheckBounds    ; voyons si le tank ne sort pas des limites
  107.     bsr    MoveMiner    ; puis déplaçons-le
  108.     move.l    Width(pc),d0    ; le tank est-il sur le bord droit ?
  109.     subq.l    #1,d0
  110.     cmp.w    MinerX(pc),d0
  111.     bne.s    NoGoal
  112.     move.l    Height(pc),d0    ; le tank est-il en bas ?
  113.     subq.l    #1,d0
  114.     cmp.w    MinerY(pc),d0
  115.     bne.s    NoGoal        ; oui ! le but est atteint ! (Félicitations!)
  116.     lea    Won.MSG(pc),a0    ; Affiche le message de fin
  117.     bra.s    EndOfGame    ; et termine le jeu
  118.  
  119. NoGoal    moveq    #0,d0        ; But pas encore atteint
  120.     move.w    MinerY(pc),d0    ; Transforme la position du tank en un offset
  121.     mulu    Width+2(pc),d0    ; pour la matrice: offset=Width*Y+X
  122.     add.w    MinerX(pc),d0
  123.     lea    Mines.Array(pc),a2
  124.     tst.b    (a2,d0)        ; Regarde si le tank est sur une mine
  125.     beq.s    ShowNumber    ; Non!!
  126.  
  127.     lea    Lost.MSG(pc),a0    ; Uh-Oh: une mine !
  128. EndOfGame
  129.     st    FinishFlag    ; Le jeu est terminé
  130.     bsr    DisplayStatus    ; Affiche le message de fin (gagné ou perdu)
  131.     bsr    RevealMines    ; et révèle la position des mines
  132.     bra    NextMessage    ; Reboucle
  133. NewGame
  134.     clr.b    FinishFlag    ; Quand un jeu commence,il n'est pas fini
  135.     move.l    YAMFG.RastPort(pc),a1
  136.     moveq    #RP_JAM2,d0
  137.     move.l    Graphics.Base(pc),a6
  138.     jsr    _LVOSetDrMd(a6)    ; mode de dessin:RP_JAM2 (deux couleurs)
  139.     move.l    YAMFG.RastPort(pc),a1
  140.     moveq    #0,d0
  141.     jsr    _LVOSetAPen(a6)    ; choisit couleur 0
  142.     move.l    YAMFG.RastPort(pc),a1
  143.     move.l    #4,d0    ; dessine un gros rectange pour effacer l'affichage
  144.     move.l    #12,d1
  145.     move.l    #396,d2
  146.     move.l    #196,d3
  147.     jsr    _LVORectFill(a6)
  148.     bsr    DrawMinesBorder    ; dessine un border autour de l'aire de jeu
  149.     bsr    PlaceMines    ; Génère les positions aléatoires des mines
  150.     clr.w    MinerX    ; Place le tank dans le coin supérieur gauche
  151.     clr.w    MinerY
  152.     bsr    ShowMiner    ; dessine le tank
  153.  
  154. ShowNumber
  155.     lea    Mines.Array(pc),a2
  156.     moveq    #0,d0
  157.     move.w    MinerY(pc),d0    ; change la position du tank en offset
  158.     mulu    Width+2(pc),d0
  159.     add.w    MinerX(pc),d0
  160.     add.l    d0,a2        ; position du tank dans la matrice
  161.     moveq    #0,d1
  162.     move.l    Width(pc),d3    ; d3=Largeur de l'aire de jeu
  163.     move.l    Height(pc),d4
  164.     move.l    d3,d5        ; d5=Largeur-1
  165.     subq.l    #1,d5
  166.     subq.l    #1,d4        ; d4=Hauteur-1
  167.     move.l    d3,d6
  168.     neg.l    d6        ; d6=-Largeur
  169.     tst.w    MinerY        ; tank sur le bord haut ?
  170.     beq.s    No9        ; oui? alors ne teste pas au-dessus!
  171.     tst.b    (a2,d6.l)    ; mine en position 8 ?
  172.     beq.s    No8        ; note: Je suis ces conventions dans le
  173.     addq.l    #1,d1        ; source: 789
  174. No8    tst.w    MinerX        ;         4 6
  175.     beq.s    No7        ;         123
  176.     tst.b    -1(a2,d6.l)    ; si la grille dans la position testée (par
  177.     beq.s    No7        ; ordre d'apparition:8,7,9,4,6,1,2,3) ne
  178.     addq.l    #1,d1        ; contient pas zero,alors il y a une mine,et
  179. No7    cmp.w    MinerX(pc),d5    ; Le compteur de mines (d1) est incrémenté
  180.     beq.s    No9        ; Bien sûr,si la position n'existe pas
  181.     tst.b    1(a2,d6.l)    ; (si le tank est sur un bord de l'aire de
  182.     beq.s    No9        ; jeu),la position n'est pas testée.
  183.     addq.l    #1,d1
  184. No9    tst.w    MinerX
  185.     beq.s    No4
  186.     tst.b    -1(a2)
  187.     beq.s    No4
  188.     addq.l    #1,d1
  189. No4    cmp.w    MinerX(pc),d5
  190.     beq.s    No6
  191.     tst.b    1(a2)
  192.     beq.s    No6
  193.     addq.l    #1,d1
  194. No6    cmp.w    MinerY(pc),d4
  195.     beq.s    No3
  196.     tst.w    MinerX
  197.     beq.s    No1
  198.     tst.b    -1(a2,d3)
  199.     beq.s    No1
  200.     addq.l    #1,d1
  201. No1    tst.b    (a2,d3)
  202.     beq.s    No2
  203.     addq.l    #1,d1
  204. No2    cmp.w    MinerX(pc),d5
  205.     beq.s    No3
  206.     tst.b    1(a2,d3)
  207.     beq.s    No3
  208.     addq.l    #1,d1
  209. No3
  210.     add.b    #'0',d1    ; change le compteur de mines en un chiffre affichable
  211.     move.b    d1,Mines.Number    ; et range-le pour l'afficher
  212.     lea    MinesNumber.MSG(pc),a0    ; Le message 'Mines around you'
  213.     bsr    DisplayStatus    ; affiche-le!
  214.     bra    NextMessage    ; prochaine action du joueur...
  215.  
  216. NoRawKey
  217.     cmp.l    #IDCMP_MENUPICK,d7    ; un menu sélectionné ?
  218.     bne    NextMessage    ; non: ignore ce message étrange!
  219. DoNextSelect
  220.     move.w    d6,d0        ; le menu number donné par Intuition
  221.     lea    Project.Menu(pc),a0    ; notre barre de menu
  222.     move.l    Intuition.Base(pc),a6
  223.     jsr    _LVOItemAddress(a6)    ; adresse du MenuItem choisi
  224.     move.l    d0,a5
  225.     tst.l    d0    ; y en a-t-il vraiment un ?
  226.     beq    NextMessage    ; Non: fin du traitement des menus
  227.     move.w    mi_NextSelect(a5),d6    ; stocke le menunumber suivant
  228.     move.l    mi_SIZEOF(a5),a1    ; Ceci est un champ non standard de
  229.     cmp.l    #0,a1    ; la structure MenuItem:  la routine à executer...
  230.     beq    DoNextSelect    ; si il y en a une bien sûr
  231.     jsr    (a1)    ; execute-la !
  232.     bra.s    DoNextSelect    ; puis examine la sélection suivante
  233.  
  234. ClearMenus    ; Temps de quitter le jeu !!
  235.     move.l    YAMFG.Window(pc),a0    ; retire les menus de la fenêtre
  236.     move.l    Intuition.Base(pc),a6
  237.     jsr    _LVOClearMenuStrip(a6)
  238. CloseWindow
  239.     move.l    YAMFG.Window(pc),a0    ; ferme la fenêtre
  240.     move.l    Intuition.Base(pc),a6
  241.     jsr    _LVOCloseWindow(a6)
  242. CloseReqTools
  243.     move.l    ReqTools.Base(pc),a1    ; ferme la reqtools.library
  244.     move.l    4.w,a6
  245.     jsr    _LVOCloseLibrary(a6)
  246. OutOfHere
  247.     move.l    WBStarter(pc),d1    ; venons-nous du Workbench ?
  248.     beq.s    BackToCLI    ; non: plus rien à faire
  249.     jsr    _LVOForbid(a6)    ; oui: nous devons répondre au message
  250.     move.l    d1,a1    ; WBStartup que nous avons reçu au début
  251.     move.l    4.w,a6        ; notez que Forbid() est absolument nécessaire
  252.     jsr    _LVOReplyMsg(a6)
  253. BackToCLI
  254.     moveq    #0,d0    ; pour que le CLI n'affiche pas d'étranges codes
  255.     rts    ; C'est la triste fin ...
  256.  
  257. ; sous-routine qui initialise quelques variables d'affichage et dessine
  258. ; un bord rectangulaire et affiche l'image de la cible
  259. DrawMinesBorder
  260.     movem.l    d0-d1/a0-a1/a6,-(sp)
  261.     move.l    Width(pc),d0    ; Largeur en pixels=Largeur*16
  262.     lsl.l    #4,d0
  263.     move.l    Height(pc),d1    ; Hauteur en pixels=Hauteur*8
  264.     lsl.l    #3,d1
  265.     addq.l    #1,d0
  266.     addq.l    #1,d1
  267.     move.w    d0,Border.Right1    ; stocke ces valeurs pour dessiner
  268.     move.w    d0,Border.Right2    ; le cadre
  269.     move.w    d0,Border.Right3
  270.     move.w    d1,Border.Bot1
  271.     move.w    d1,Border.Bot2
  272.     move.w    d1,Border.Bot3
  273.     move.l    YAMFG.RastPort(pc),a0    ; le RastPort de la fenêtre
  274.     lea    YAMFG.Border(pc),a1    ; la structure Border
  275.     move.l    Width(pc),d0    ; Calcule la variable PlayX pour centrer
  276.     lsl.l    #3,d0    ; l'aire de jeu: PlayX=(400-Width*16)/2
  277.     neg.l    d0    ; PlayX=200-Width*8
  278.     add.l    #200,d0
  279.     move.l    d0,PlayX
  280.     move.l    Height(pc),d1    ; Calcule PlayY de façon similaire
  281.     lsl.l    #2,d1    ; PlayY=(200-Height*8)/2=100-Height*4
  282.     neg.l    d1
  283.     add.l    #100,d1
  284.     addq.l    #3,d1    ; et ajoute 3 pixels
  285.     cmp.l    #STATUSY+4,d1    ; mais ne déborde pas sur la ligne de status
  286.     bge.s    NotTooLow
  287.     move.l    #STATUSY+4,d1    ; Si c'est le cas,descends un peu
  288. NotTooLow
  289.     move.l    d1,PlayY
  290.     move.l    Intuition.Base(pc),a6
  291.     jsr    _LVODrawBorder(a6)    ; Dessine-le,ce cadre
  292.     move.l    YAMFG.RastPort(pc),a0    ; Nécessaire pour tous les graphismes
  293.     lea    Target.Image,a1    ; La structure image pour la cible
  294.     move.l    Width(pc),d0    ; position X Y de la cible
  295.     subq.l    #1,d0    ; dans le coin inférieur droit
  296.     lsl.l    #4,d0
  297.     add.l    PlayX(pc),d0
  298.     move.l    Height(pc),d1
  299.     subq.l    #1,d1
  300.     lsl.l    #3,d1
  301.     add.l    PlayY(pc),d1
  302.     jsr    _LVODrawImage(a6)    ; Intuition la dessine.
  303.     movem.l    (sp)+,d0-d1/a0-a1/a6
  304.     rts
  305.  
  306. ; ceci est la routine qui place aléatoirement les mines dans la grille
  307. ; il n'est PAS garanti qu'il y ait moyen de passer si les mines sont trop
  308. ; nombreuses. La routine utilise un algorythme FastRand() classique,avec
  309. ; la position du raster pour graine
  310. PlaceMines
  311.     movem.l    d0/d3-d5/a2,-(sp)
  312.     lea    Mines.Array(pc),a2    ; grille à remplir
  313.     move.l    Width(pc),d0
  314.     mulu    Height+2(pc),d0    ; Taille de la grille
  315.     move.l    d0,d3
  316.     subq.l    #1,d0    ; une boucle dbra décompte jusqu'à -1
  317. ClearMines
  318.     clr.b    (a2)+    ; enlève toutes les mines de la grille
  319.     dbra    d0,ClearMines
  320.     moveq    #0,d5
  321.     move.w    $DFF000+vhposr,d5    ; obtient la graine de la position raster
  322.     lea    Mines.Array(pc),a2    ; récupère a2
  323.     move.l    Mines(pc),d4    ; nombre de mines à placer
  324.     cmp.l    d4,d3    ; est-ce possible ??
  325.     bgt.s    AnotherRandom    ; oui
  326.     move.l    d3,d4    ; il y a beaucoup trop de mines !! Réduis leur nombre
  327.     subq.l    #4,d4    ; c'est seulement une sécurité:qui jouerait une partie
  328. AnotherRandom        ; où chaque mouvement est perdu ?
  329.     add.l    d5,d5    ; Voici la routine FastRand() qui génère une série
  330.     bhi.s    .NoEOR    ; de nombres apparamment aléatoire
  331.     eor.l    #$1D872B41,d5    ; Pourquoi ce nombre ? Bonne question.
  332. .NoEOR
  333.     moveq    #0,d0    ; divise le nombre aléatoire par la taille de la
  334.     move.w    d5,d0    ; grille pour que le reste soit une position valide
  335.     divu    d3,d0
  336.     swap    d0
  337.     tst.w    d0    ; Pas de mine dans le coin supérieur gauche
  338.     beq    AnotherRandom
  339.     tst.b    (a2,d0.w)    ; Y a-t-il déjà une mine ici ?
  340.     bne.s    AnotherRandom    ; Oui?? Alors utilise un autre offset
  341.     move.b    #1,(a2,d0.w)    ; Non: maintenant y en a une
  342.     subq    #1,d4    ; Etait-ce la dernière mine à placer ?
  343.     bne    AnotherRandom    ; Non.
  344.     movem.l    (sp)+,d0/d3-d5/a2    ; Oui: récupère les registres et
  345.     rts    ; retourne
  346.  
  347. ; Ceci affiche le tank..
  348. ShowMiner
  349.     movem.l    d0-d1/a0-a1/a6,-(sp)
  350.     move.l    YAMFG.RastPort(pc),a0
  351.     lea    Tank.Image,a1    ; Structure image pour le tank
  352.     moveq    #0,d0
  353.     move.l    d0,d1
  354.     move.w    MinerX(pc),d0
  355.     move.w    MinerY(pc),d1
  356.     lsl.l    #4,d0
  357.     lsl.l    #3,d1
  358.     add.l    PlayX(pc),d0    ; X=PlayX+MinerX*16
  359.     add.l    PlayY(pc),d1    ; Y=PlayY+MinerY*8
  360.     move.l    Intuition.Base(pc),a6
  361.     jsr    _LVODrawImage(a6)    ; Dessine-le. Facile non?
  362.     movem.l    (sp)+,d0-d1/a0-a1/a6
  363.     rts
  364.  
  365. ; Ceci regarde si le tank est sorti des limites,auquel cas il est remis sur
  366. ; le bord de la grille. Cette routine est appelée avec la nouvelle position
  367. ; souhaitée en D0 et D1 (X et Y respectivement).
  368. CheckBounds
  369.     ext.l    d0    ; Change l'abscisse en un mot long
  370.     cmp.l    Width(pc),d0    ; Trop loin sur la droite ?
  371.     blt.s    NotRightEdge
  372.     move.l    Width(pc),d0
  373.     subq.l    #1,d0
  374. NotRightEdge
  375.     tst.l    d0        ; Trop loin sur la gauche ?
  376.     bge.s    NotLeftEdge
  377.     moveq    #0,d0
  378. NotLeftEdge
  379.     ext.l    d1    ; Change l'ordonnée en un mot long
  380.     tst.l    d1        ; Trop haut ?
  381.     bge.s    NotUpEdge
  382.     moveq    #0,d1
  383. NotUpEdge
  384.     cmp.l    Height(pc),d1    ; Trop bas ?
  385.     blt.s    NoDownEdge
  386.     move.l    Height(pc),d1
  387.     subq.l    #1,d1
  388. NoDownEdge
  389.     rts
  390.  
  391. ; Cette routine efface l'image du tank et la redessine à la position donnée
  392. ; par D0 et D1 (X et Y). Elle actualise aussi les variables MinerX et MinerY
  393. MoveMiner
  394.     bsr.s    EraseMiner
  395.     move.w    d0,MinerX
  396.     move.w    d1,MinerY
  397.     bra    ShowMiner
  398.  
  399. ; Ceci efface l'image du tank en affichant deux espaces en couleur 3
  400. EraseMiner
  401.     movem.l    d0-d1/a0-a1/a6,-(sp)
  402.     move.l    YAMFG.RastPort(pc),a1
  403.     moveq    #0,d0    ; X=PlayX+MinerX*16
  404.     move.l    d0,d1    ; Y=PlayY+MinerY*8
  405.     move.w    MinerX(pc),d0
  406.     move.w    MinerY(pc),d1
  407.     lsl.l    #4,d0
  408.     lsl.l    #3,d1
  409.     add.l    PlayX(pc),d0
  410.     add.l    PlayY(pc),d1
  411.     addq.l    #6,d1    ; Ajoute 6 à la position Y pour la ligne de base
  412.     move.l    Graphics.Base(pc),a6    ; de la fonte topaz standard.
  413.     jsr    _LVOMove(a6)    ; Déplace le curseur graphique
  414.     move.l    YAMFG.RastPort(pc),a1
  415.     moveq    #3,d0    ; couleur B égale 3 (orange ou bleu sur les Workbenchs
  416.     jsr    _LVOSetBPen(a6)    ; normalement colorés)
  417.     move.l    YAMFG.RastPort(pc),a1
  418.     moveq    #RP_JAM2,d0    ; drawmode: RP_JAM2 pour que les espaces
  419.     jsr    _LVOSetDrMd(a6)    ; soient réellement en bleu
  420.     lea    Space.Text(pc),a0
  421.     move.l    YAMFG.RastPort(pc),a1
  422.     moveq    #2,d0    ; Il y en a deux
  423.     jsr    _LVOText(a6)
  424.     movem.l    (sp)+,d0-d1/a0-a1/a6
  425.     rts    ; That's it
  426.  
  427. ; Cette routine sert à effacer la ligne status. Elle est appelée par DisplayStatus
  428. EraseStatus
  429.     movem.l    d0-d3/a0-a1/a6,-(sp)
  430.     move.l    YAMFG.RastPort(pc),a1
  431.     moveq    #RP_JAM2,d0
  432.     move.l    Graphics.Base(pc),a6
  433.     jsr    _LVOSetDrMd(a6)    ; Drawmode: RP_JAM2
  434.     move.l    YAMFG.RastPort(pc),a1
  435.     moveq    #0,d0    ; couleur A= 0
  436.     jsr    _LVOSetAPen(a6)
  437.     move.l    YAMFG.RastPort(pc),a1
  438.     move.l    #STATUSX,d0    ; coordonnées pour le rectangle qui sera des-
  439.     move.l    #STATUSY-6,d1    ; siné par dessus la ligne status
  440.     move.l    #STATUSX+40*8,d2
  441.     move.l    #STATUSY+2,d3
  442.     jsr    _LVORectFill(a6)    ; dessine le rectangle
  443.     movem.l    (sp)+,d0-d3/a0-a1/a6
  444.     rts
  445.  
  446. ; Cette routine affiche un message dans la ligne status,auparavant effacée.
  447. ; A0 est un pointeur sur le message à afficher.
  448. DisplayStatus:            ;DisplayStatus(Message)(A0)
  449.     movem.l    d0-d1/a0-a2/a6,-(sp)
  450.     bsr    EraseStatus    ; Efface d'abord la ligne status
  451.     move.l    a0,a2    ; Sauve le pointeur sur le message (A2 est obligatoi-
  452.     move.l    YAMFG.RastPort(pc),a1    ; rement préservé par les librairies)
  453.     moveq    #RP_JAM1,d0
  454.     move.l    Graphics.Base(pc),a6
  455.     jsr    _LVOSetDrMd(a6)    ; drawmode: RP_JAM1: seule la couleur A est
  456.     move.l    YAMFG.RastPort(pc),a1    ; utilisée.
  457.     moveq    #1,d0
  458.     jsr    _LVOSetAPen(a6)    ; Couleur A=1 (normalement noir ou blanc)
  459.     move.l    YAMFG.RastPort(pc),a1
  460.     move.l    #STATUSX,d0    ; Coordonnées de la ligne status
  461.     move.l    #STATUSY,d1
  462.     jsr    _LVOMove(a6)    ; déplace le curseur graphique
  463.     move.l    a2,a0
  464. .LenLoop        ; compte la longueur du message
  465.     tst.b    (a2)+    ; nécessaire pour la fonction Text()
  466.     bne    .LenLoop
  467.     sub.l    a0,a2
  468.     subq.l    #1,a2
  469.     move.l    a2,d0
  470.     move.l    YAMFG.RastPort(pc),a1
  471.     jsr    _LVOText(a6)    ; affiche le texte
  472.     movem.l    (sp)+,d0-d1/a0-a2/a6
  473.     rts
  474.  
  475. ; Cette routine révèle l'emplacement des mines,appelée quand le jeu est
  476. ; terminé (le joueur a gagné ou perdu)
  477. RevealMines
  478.     movem.l    d0-d3/a0-a2/a6,-(sp)
  479.     lea    Mines.Array(pc),a2    ; La grille des mines
  480.     moveq    #-1,d2        ; La position actuelle dans la grille
  481.     move.l    Intuition.Base(pc),a6
  482.     move.l    Width(pc),d3
  483.     mulu    Height+2(pc),d3    ; d3 est la taille de la grille
  484. RevealLoop
  485.     addq.l    #1,d2    ; incrémente la position
  486.     cmp.l    d3,d2    ; havons nous atteint la fin de la grille ?
  487.     beq.s    EndOfReveal    ; oui...alors fini.
  488.     tst.b    (a2)+    ; y a-t-il une mine ici ?
  489.     beq.s    RevealLoop    ; Non, position suivante
  490.     move.l    d2,d0    ; oui! sa position est en D0
  491.     divu    Width+2(pc),d0    ; pour séparer les coordonnées X et Y
  492.     moveq    #0,d1    ; abscisse (le reste de la division) en D0
  493.     move.w    d0,d1    ; ordonnée en D1 (le quotient de la division)
  494.     clr.w    d0
  495.     swap    d0
  496.     move.l    YAMFG.RastPort(pc),a0
  497.     lea    Mine.Image,a1    ; structure Image pour une mine
  498.     lsl.l    #4,d0    ; Change X et Y de la grille en véritable coordonnées
  499.     lsl.l    #3,d1    ; graphiques
  500.     add.l    PlayX(pc),d0
  501.     add.l    PlayY(pc),d1
  502.     jsr    _LVODrawImage(a6)    ; Dessine une mine
  503.     bra    RevealLoop    ; contine avec les autres positions
  504. EndOfReveal
  505.     movem.l    (sp)+,d0-d3/a0-a2/a6    ; toutes les mines affichées,on a
  506.     rts    ; fini notre travail
  507.  
  508. ; Cette routine est appelée quand le menu correspondant est sélectionné
  509. QuitYAMFG
  510.     addq.l    #4,sp    ; Pas de retour pour cette routine
  511.     bra    ClearMenus    ; Nous partons!
  512.  
  513. ; Appelé quand le joueur a chois 'About' dans les menus
  514. ShowAbout
  515.     movem.l    d0-d1/a0-a4/a6,-(sp)
  516.     lea    About.Body(pc),a1    ; message principal
  517.     lea    About.Gad(pc),a2    ; Texte pour le gadget
  518.     suba.l    a3,a3    ; pas de structure ReqInfo
  519.     move.l    a3,a4    ; et pas de formattage
  520.     lea    About.TagList(pc),a0    ; TagList spécifique
  521.     move.l    ReqTools.Base(pc),a6    ; Laissons la reqtools.library
  522.     jsr    _LVOrtEZRequestA(a6)    ; le faire...
  523.     movem.l    (sp)+,d0-d1/a0-a4/a6
  524.     rts
  525.  
  526. ; Quand l'utilisateur veut changer le nombre de mines (avec le menu)
  527. ModifyMines
  528.     lea    Mines(pc),a1    ; Variable qui contient le nombre de mines
  529.     lea    HowManyMines.Title(pc),a2    ; Titre pour le requester
  530.     suba.l    a3,a3    ; pas de ReqInfo
  531.     lea    Mines.TagList(pc),a0    ; mais quelques tags...
  532.     move.l    ReqTools.Base(pc),a6    ; Demande le nombre de mines
  533.     jsr    _LVOrtGetLongA(a6)
  534.     tst.l    d0    ; l'utilisateur a entré un nombre valide ?
  535.     bne.s    NewMines    ; oui, nouvelle partie
  536.     rts    ; non, requester annulé
  537.  
  538. ; Il veut changer la largeur de l'aire de jeu
  539. ChangeWidth
  540.     lea    Width(pc),a1    ; Variable pour la largeur
  541.     lea    Width.Title(pc),a2    ; Titre du requester
  542.     sub.l    a3,a3
  543.     lea    Width.TagList(pc),a0    ; quelques tags...
  544.     move.l    ReqTools.Base(pc),a6
  545.     jsr    _LVOrtGetLongA(a6)    ; Nouvelle largeur demandée
  546.     tst.l    d0
  547.     bne.s    NewWidth    ; Nouvelle partie si c'est valide
  548.     rts    ; retourne si le requester a été annulé
  549. NewMines    ; un branch pour les routines qui nécessitent une nouvelle
  550. NewWidth    ; partie
  551. NewHeight
  552.     addq.l    #4,sp    ; corrige la pile pour l'adresse de retour
  553.     bra    NewGame    ; et branche sur le programme principal
  554.  
  555. ; Exactement la même routine que ChangeWidth(). Je ne crois pas que des
  556. ; commentaires soient nécessaires.
  557. ChangeHeight
  558.     lea    Height(pc),a1
  559.     lea    Height.Title(pc),a2
  560.     sub.l    a3,a3
  561.     lea    Height.TagList(pc),a0
  562.     move.l    ReqTools.Base(pc),a6
  563.     jsr    _LVOrtGetLongA(a6)
  564.     tst.l    d0
  565.     bne.s    NewHeight
  566.     rts
  567.  
  568. ; Cette partie contient des données pour les fenêtres,menus,messages,et
  569. ; quelques petites choses diverses.
  570. YAMFG.NewWindow    ; la structure NewWindow
  571.     dc.w    120,0    ; origine XY
  572.     dc.w    400,200    ; Largeur et hauteur en pixels
  573.     dc.b    0,1    ; couleurs FrontPen et BackPen
  574.     dc.l    IDCMP_CLOSEWINDOW!IDCMP_RAWKEY!IDCMP_MENUPICK
  575. ; La ligne ci-dessus contient les flags IDCMP, un message sera envoyé par
  576. ; Intuition à notre programme quand ces évenements arriveront.
  577.     dc.l    WINDOWDRAG!WINDOWDEPTH!WINDOWCLOSE!ACTIVATE!NOCAREREFRESH
  578. ; Ce sont des flags standards pour les fenêtres. Il n'y a pas de flag exo-
  579. ; tique,ils sont évidents par leur nom,vous devriez les comprendre vous-
  580. ; même,donc pas besoin de commentaires supplémentaires, alors pourquoi
  581. ; est-ce que je vous ennuie avec ça ?
  582.     dc.l    0    ; Pas de gadgets sur cette fenêtre
  583.     dc.l    0    ; Pas de CheckMark particulier (on n'en utilise même pas)
  584.     dc.l    YAMFG.WindowName    ; Nom de notre fenêtre
  585.     dc.l    0    ; Ecran: on se contentera de celui du Workbench
  586.     dc.l    0    ; Bitmap: pas de bitmap.
  587.     dc.w    400,200    ; dimensions minimales (inutiles ici)
  588.     dc.w    400,200    ; dimensions maximales (idem)
  589.     dc.w    WBENCHSCREEN    ; oui,l'écran du workbench
  590.  
  591. YAMFG.Border    ; structures Border pour le rectangle autour de l'aire de jeu
  592.     dc.w    -1,-1    ; origine XY
  593.     dc.b    1,0,RP_JAM1,3    ; FontPen,BackPen,DrawMode,Nombre de vecteurs
  594.     dc.l    YAMFG.Vectorsa,YAMFG.Borderb    ; Vecteurs,border suivant
  595. YAMFG.Borderb
  596.     dc.w    -1,-1        ; on utilise 2 borders pour créer un effet
  597.     dc.b    2,0,RP_JAM1,3    ; de pseudo-3D (un coté en blanc,l'autre en
  598.     dc.l    YAMFG.Vectorsb,0    ; noir)
  599.  
  600. YAMFG.Vectorsa    ; Les coordonnées pour les vecteurs du premier border
  601.     dc.w    0    ; Certaines seront changées par le programme.
  602. Border.Bot1
  603.     dc.w    DEFAULT_HEIGHT*8+1
  604.     dc.w    0,0
  605. Border.Right1
  606.     dc.w    DEFAULT_WIDTH*16+1,0
  607.  
  608. YAMFG.Vectorsb    ; Même chose pour le second border
  609. Border.Right2
  610.     dc.w    DEFAULT_WIDTH*16+1,1
  611. Border.Right3
  612.     dc.w    DEFAULT_WIDTH*16+1
  613. Border.Bot2
  614.     dc.w    DEFAULT_HEIGHT*8+1
  615.     dc.w    1
  616. Border.Bot3
  617.     dc.w    DEFAULT_HEIGHT*8+1
  618.  
  619. Project.Menu    ; Voici la structure menu pour le menu project
  620.     dc.l    Options.Menu    ; Menu suivant: 'Options'
  621.     dc.w    0,0    ; Bord gauche et haut
  622.     dc.w    63,0    ; Largeur et hauteur (Hauteur inutilisée)
  623.     dc.w    MENUENABLED    ; Flags: le menu est autorisé
  624.     dc.l    Project.Name    ; devinez ce que c'est
  625.     dc.l    About.MenuItem    ; Premier item de ce menu
  626.     dc.w    0,0,0,0    ; variables Intuition mystérieuses
  627.  
  628. About.MenuItem    ; structure MenuItem pour l'item 'About'
  629.     dc.l    Quit.MenuItem    ; Item suivant
  630.     dc.w    0,0    ; Bord gauche,Bord haut
  631.     dc.w    104,8    ; Largeur,Hauteur
  632.     dc.w    ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP    ; menu flags:
  633. ; ITEMTEXT signifie qu'une structure IntuiText sera utilisée (ç'aurait pu
  634. ; être une Image),COMMSEQ signifie qu'il y a un raccourci clavier,ITEMENABLED
  635. ; que l'item peut être sélectionné,HIGHCOMP dit à Intuition d'inverser les
  636. ; couleurs du menu si le pointeur de souris passe dessus
  637.     dc.l    0    ; Pas d'exclusion mutuelle
  638.     dc.l    About.IText    ; Render: une structure IntuiText
  639.     dc.l    0    ; Pas de rendering pour l'état sélectionné
  640.     dc.b    'A'    ; Raccourci clavier
  641.     dc.b    0    ; Un octet de remplissage pour avoir une adresse paire
  642.     dc.l    0    ; pas de liste de SubItems
  643.     dc.w    MENUNULL    ; sera rempli par Intuition pour la sélection
  644. ; étendue
  645.     dc.l    ShowAbout    ; Champ non standard,utilisé par le prog
  646. ; pour determiner la routine à executer quand le menu est sélectionné
  647. About.IText    ; Une structure IntuiText pour le MenuItem
  648.     dc.b    3,1,RP_COMPLEMENT,0    ; DetailPen,BlockPen,DrawMode,FillByte
  649.     dc.w    0,0    ; Bord gauche,Bord haut
  650.     dc.l    0    ; fonte par défaut
  651.     dc.l    About.MSG    ; Message
  652.     dc.l    0    ; Pas d'autre structure IntuiText
  653.  
  654. ; Les autres Menus et MenuItems sont faits de la même façon,ce serait une
  655. ; perte de temps de tous les décrire.
  656.  
  657. Quit.MenuItem
  658.     dc.l    0
  659.     dc.w    0,8
  660.     dc.w    104,8
  661.     dc.w    ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP
  662.     dc.l    0
  663.     dc.l    Quit.IText
  664.     dc.l    0
  665.     dc.b    'Q'
  666.     dc.b    0
  667.     dc.l    0
  668.     dc.w    MENUNULL
  669.     dc.l    QuitYAMFG
  670. Quit.IText
  671.     dc.b    3,1,RP_COMPLEMENT,0
  672.     dc.w    0,0
  673.     dc.l    0
  674.     dc.l    Quit.MSG
  675.     dc.l    0
  676.  
  677. Options.Menu
  678.     dc.l    0
  679.     dc.w    70,0
  680.     dc.w    63,0
  681.     dc.w    MENUENABLED
  682.     dc.l    Options.Name
  683.     dc.l    Mines.MenuItem
  684.     dc.w    0,0,0,0
  685.  
  686. Mines.MenuItem
  687.     dc.l    Width.MenuItem
  688.     dc.w    0,0
  689.     dc.w    184,8
  690.     dc.w    ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP
  691.     dc.l    0
  692.     dc.l    Mines.IText
  693.     dc.l    0
  694.     dc.b    'M'
  695.     dc.b    0
  696.     dc.l    0
  697.     dc.w    MENUNULL
  698.     dc.l    ModifyMines
  699. Mines.IText
  700.     dc.b    3,1,RP_COMPLEMENT,0
  701.     dc.w    0,0
  702.     dc.l    0
  703.     dc.l    Mines.MSG
  704.     dc.l    0
  705.  
  706. Width.MenuItem
  707.     dc.l    Height.MenuItem
  708.     dc.w    0,8
  709.     dc.w    184,8
  710.     dc.w    ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP
  711.     dc.l    0
  712.     dc.l    Width.IText
  713.     dc.l    0
  714.     dc.b    'W'
  715.     dc.b    0
  716.     dc.l    0
  717.     dc.w    MENUNULL
  718.     dc.l    ChangeWidth
  719. Width.IText
  720.     dc.b    3,1,RP_COMPLEMENT,0
  721.     dc.w    0,0
  722.     dc.l    0
  723.     dc.l    Width.MSG
  724.     dc.l    0
  725.  
  726. Height.MenuItem
  727.     dc.l    0
  728.     dc.w    0,16
  729.     dc.w    184,8
  730.     dc.w    ITEMTEXT!COMMSEQ!ITEMENABLED!HIGHCOMP
  731.     dc.l    0
  732.     dc.l    Height.IText
  733.     dc.l    0
  734.     dc.b    'H'
  735.     dc.b    0
  736.     dc.l    0
  737.     dc.w    MENUNULL
  738.     dc.l    ChangeHeight
  739. Height.IText
  740.     dc.b    3,1,RP_COMPLEMENT,0
  741.     dc.w    0,0
  742.     dc.l    0
  743.     dc.l    Height.MSG
  744.     dc.l    0
  745.  
  746. About.TagList    ; Les tags pour le requester "about"
  747.     dc.l    RT_IDCMPFlags,IDCMP_MOUSEBUTTONS!INACTIVEWINDOW
  748. ; Des flags IDCMP supplémentaires pour réagir
  749.     dc.l    RTEZ_Flags,EZREQF_CENTERTEXT    ; Centre le texte
  750.     dc.l    TAG_END
  751.  
  752. Mines.TagList    ;Tags pour le requester "nombre de mines"
  753.     dc.l    RTGL_Min,1    ; Minimum 1
  754.     dc.l    RTGL_Max,100    ; Maximum 100
  755.     dc.l    TAG_END
  756.  
  757. Width.TagList    ; Pour le requester de la largeur
  758.     dc.l    RTGL_Min,4    ; Minimum 4
  759.     dc.l    RTGL_Max,MAX_WIDTH    ; Maximum
  760.     dc.l    TAG_END
  761.  
  762. Height.TagList    ; Pour le requester de la hauteur
  763.     dc.l    RTGL_Min,4    ; Minimum
  764.     dc.l    RTGL_Max,MAX_HEIGHT    ; Maximum
  765.     dc.l    TAG_END
  766.  
  767. Project.Name    ; Pas besoin de commentaires
  768.     dc.b    'Project',0
  769. About.MSG
  770.     dc.b    'About...',0
  771. Quit.MSG
  772.     dc.b    'Quit',0
  773. Options.Name
  774.     dc.b    'Options',0
  775. Mines.MSG
  776.     dc.b    'Number of mines...',0
  777. Width.MSG
  778.     dc.b    'Width...',0
  779. Height.MSG
  780.     dc.b    'Height...',0
  781.  
  782. YAMFG.WindowName
  783.     dc.b    'YAMFG 1.0 © 1993 F.Delacroix -FreeWare',0
  784. ReqTools.Name
  785.     dc.b    'reqtools.library',0    ; Nom de la reqtools.library
  786. Space.Text
  787.     dc.b    '  '    ; Utilisé pour effacer l'image du tank
  788. Lost.MSG
  789.     dc.b    'You blew up ! Press a key...',0
  790. MinesNumber.MSG
  791.     dc.b    'Number of mines around you:'
  792. Mines.Number
  793.     dc.b    '0',0
  794. Won.MSG    dc.b    'Congratulations! You''ve reached the goal!',0
  795.  
  796. About.Body    ; The about message,please dont change this.
  797.     dc.b    'YAMFG 1.0 by F.Delacroix - FreeWare',10,10
  798.     dc.b    'This program may not be used for any profit',10
  799.     dc.b    'To contact me,write to:',10
  800.     dc.b    'Frédéric DELACROIX',10
  801.     dc.b    '5 rue d''Artres',10
  802.     dc.b    '59269 QUERENAING, FRANCE',0
  803. About.Gad
  804.     dc.b    'Ah-ha.',0
  805.  
  806. HowManyMines.Title
  807.     dc.b    'How many mines ?',0
  808. Width.Title
  809.     dc.b    'New width ?',0
  810. Height.Title
  811.     dc.b    'New height ?',0
  812.  
  813. WBStarter    dc.l    0    ; WBStartup reçu (0 si CLI)
  814. Graphics.Base    dc.l    0    ; Base de la graphics.library
  815. Intuition.Base    dc.l    0    ; Base de l'intuition.library
  816. ReqTools.Base    dc.l    0    ; Base de la reqtools.library
  817. YAMFG.Window    dc.l    0    ; structure Window (pas NewWindow)
  818. YAMFG.RastPort    dc.l    0    ; RastPort de notre fenêtre
  819. YAMFG.UserPort    dc.l    0    ; Son UserPort
  820. Mines    dc.l    DEFAULT_MINES    ; Nombre de mines
  821. MinerX    dc.w    0    ; Abscisse du tank (de 0 à width-1)
  822. MinerY    dc.w    0    ; Ordonnée du tank (de 0 à height-1)
  823. Width    dc.l    DEFAULT_WIDTH    ; Largeur (en colonnes)
  824. Height    dc.l    DEFAULT_HEIGHT    ; Hauteur (en lignes)
  825. PlayX    dc.l    0    ; Offset graphique pour l'aire de jeu
  826. PlayY    dc.l    0
  827. Mines.Array    dcb.b    MAX_WIDTH*MAX_HEIGHT,0    ; Matrice qui contient les
  828. ; positions des mines. Notez que seule une partie sera utilisé car Width et
  829. ; Height peuvent ne pas être MAX_WIDTH et MAX_HEIGHT
  830. FinishFlag    dc.b    0    ; Flag mis quand le jeu est terminé
  831.  
  832.     section    Images,DATA_C
  833. ; Voici des structures qui doivent être en CHIP-ram:
  834. Tank.Image    ; structure Image pour le tank
  835.     dc.w    0,0    ; Bord gauche,Bord haut
  836.     dc.w    16,8    ; Largeur,Hauteur
  837.     dc.w    2    ; Profondeur: 4 couleurs
  838.     dc.l    Tank.ImageData    ; Données pour l'image
  839.     dc.b    $0003,$0000    ; Modèles pour les bitplanes
  840.     dc.l    0    ; Image suivante:aucune
  841. Tank.ImageData
  842.     dc.w    $0000,$001F,$0000,$7FFE,$FFFF,$FFFF,$FFFF,$7FFE
  843. ; Données pour le premier bitplane
  844.     dc.w    $07C0,$0FE0,$0FE0,$7FFE,$FFFF,$8001,$7FFE,$0000
  845. ; Données pour le second bitplane
  846.  
  847. Mine.Image    ; Structure Image pour une mine
  848.     dc.w    0,0
  849.     dc.w    16,8
  850.     dc.w    2
  851.     dc.l    Mine.ImageData
  852.     dc.b    $0001,$0000
  853.     dc.l    0
  854. Mine.ImageData
  855.     dc.w    $0000,$0000,$0000,$0000,$0FF0,$7FFE,$7FFE,$0000
  856. ; Un seul bitplane ici
  857.  
  858. Target.Image    ; Structure Image pour la cible
  859.     dc.w    0,0
  860.     dc.w    16,8
  861.     dc.w    2
  862.     dc.l    Target.ImageData
  863.     dc.b    $0003,$0000
  864.     dc.l    0
  865. Target.ImageData
  866.     dc.w    $07E0,$0FF0,$1FF8,$3E7C,$3E7C,$1FF8,$0FF0,$07E0
  867.     dc.w    $07E0,$0C30,$1818,$318C,$318C,$1818,$0C30,$07E0
  868.  
  869.